using System;

using Impact.Model.Objects;

namespace Impact.Model.Service
{
    /// <summary>
    /// data service that provides plugin data
    /// </summary>
    public class PluginService : IPluginService
    {
        #region IPluginService Members

        /// <summary>
        /// retrieves a plugin based on its registration ID
        /// </summary>
        public PagePlugin FetchByID(int registrationId)
        {
            return PagePlugin.FetchByID(registrationId);
        }

        /// <summary>
        /// retrieves all the plugins associated with the given page
        /// </summary>
        public PagePluginCollection FetchByPage(int pageId)
        {
            return new PagePluginCollection()
                .Where(PagePlugin.Columns.PageId, pageId)
                .OrderByAsc(PagePlugin.Columns.Sequence)
                .Load();
        }

        /// <summary>
        /// retrieves all the plugins associated with the given page at a given location
        /// </summary>
        public PagePluginCollection FetchByPageByLocation(int pageId, int location)
        {
            return new PagePluginCollection()
                .Where(PagePlugin.Columns.PageId, pageId)
                .Where(PagePlugin.Columns.Location, location)
                .OrderByAsc(PagePlugin.Columns.Sequence)
                .Load();
        }

        /// <summary>
        /// creates a new reference for a given plugin on a given page
        /// </summary>
        /// <param name="pageId">ID of the page to add the plugin to</param>
        /// <param name="pluginId">GUID of the plugin to add to the page</param>
        /// <param name="userId">ID of the user responsible for the change</param>
        public void Add(int pageId, Guid pluginId, Guid userId)
        {
            PagePlugin plugin = new PagePlugin();
            plugin.PageId = pageId;
            plugin.PluginId = pluginId;
            Save(plugin, userId);
        }

        /// <summary>
        /// remove the reference of the plugin on a page
        /// </summary>
        public void Remove(int registrationId)
        {
            PagePlugin.Delete(registrationId);
        }

        /// <summary>
        /// saves the plugin object and its associated parameters
        /// </summary>
        public void Save(PagePlugin pagePlugin, Guid userId)
        {
            // force parameters to reserialize
            pagePlugin.Parameters = pagePlugin.Parameters;

            pagePlugin.Save(userId);

            // renumber the 'sequence' fields
            PagePluginCollection plugins = FetchByPage(pagePlugin.PageId);
            for (int i = 0; i < plugins.Count; i++)
            {
                plugins[i].Sequence = (i + 1) * 10;
                plugins[i].Save(userId);
            }


        }

        /// <summary>
        /// saves a group of plugins
        /// </summary>
        public void Save(PagePluginCollection plugins, Guid userId)
        {
            plugins.SaveAll( userId );
        }


        #endregion
    }
}
